package open.tech.dawn.rest.module.system.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import open.tech.dawn.core.error.ServiceException;
import open.tech.dawn.rest.common.Const;
import open.tech.dawn.rest.common.annot.Menu;
import open.tech.dawn.rest.common.page.PageFactory;
import open.tech.dawn.rest.common.page.PageInfo;
import open.tech.dawn.rest.module.system.entity.UserDto;
import open.tech.dawn.rest.module.system.entity.UserEntity;
import open.tech.dawn.rest.module.system.entity.UserPwd;
import open.tech.dawn.rest.module.system.entity.UserRoles;
import open.tech.dawn.rest.module.system.enums.ManagerStatus;
import open.tech.dawn.rest.module.system.model.SysUser;
import open.tech.dawn.rest.module.system.query.UserQuery;
import open.tech.dawn.rest.module.system.service.ISysRoleService;
import open.tech.dawn.rest.module.system.service.ISysUserService;
import open.tech.dawn.web.core.aop.Permission;
import open.tech.dawn.web.core.controller.BaseController;
import open.tech.dawn.web.core.support.Result;
import open.tech.dawn.web.util.MD5Util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 管理员表 前端控制器
 * </p>
 *
 * @author joss
 * @since 2019-11-07
 */
@RestController
@RequestMapping("/system/sysUser")
@Menu(name = "用户管理", icon = "fa fa-user-o", code = "mgr", url = "/views/system/user/user", order = 1, page = true, parentCode = "system")
public class SysUserController extends BaseController {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysRoleService sysRoleService;


    /**
     * 用户信息
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @Permission
    @Menu(name = "用户信息", code = "mgr_info", parentCode = "mgr")
    public Object selfInfo() {
        SysUser user = this.sysUserService.getById(getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("roleName", sysRoleService.getRoleNameByIds(user.getRoleid()));
        return Result.createSuccess(map);
    }

    /**
     * 用户信息
     */
    @RequestMapping(value = "/user_info", method = RequestMethod.GET)
    @Permission
    @Menu(name = "用户信息详情", code = "mgr_user_info", parentCode = "mgr")
    public Object userEdit(String userId) {
        if (StrUtil.isEmpty(userId)) {
            throw new ServiceException("请求为空");
        }
        SysUser user = this.sysUserService.getById(userId);
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("roleName", sysRoleService.getRoleNameByIds(user.getRoleid()));
        return Result.createSuccess(map);
    }

    /**
     * 修改当前用户的密码
     */
    @RequestMapping("/changePwd")
    @Permission
    @Menu(name = "修改当前用户的密码", code = "mgr_changePwd", parentCode = "mgr")
    public Object changePwd(@RequestBody UserPwd userPwd) {
        if (!userPwd.getNewPwd().equals(userPwd.getRePwd())) {
            throw new ServiceException("两个密码不一致");
        }
        String userId = getUserId();
        SysUser user = sysUserService.getById(userId);
        String oldMd5 = MD5Util.encrypt(userPwd.getOldPwd(), user.getSalt());
        if (user.getPassword().equals(oldMd5)) {
            String newMd5 = MD5Util.encrypt(userPwd.getNewPwd(), user.getSalt());
            user.setPassword(newMd5);
            user.updateById();
            return Result.createSuccess();
        } else {
            throw new ServiceException("原始密码不正确");
        }
    }

    /**
     * 查询用户列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @Permission
    @Menu(name = "查询用户列表", code = "mgr_list", parentCode = "mgr")
    public Object list(@RequestBody UserQuery query) {
        Page<UserEntity> page = new PageFactory<UserEntity>().create(query);
        page = sysUserService.selectUsers(page, query);
        return new PageInfo<>(page);
    }

    /**
     * 添加用户
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @Permission
    @Menu(name = "添加用户", code = "mgr_add", parentCode = "mgr")
    public Object add(@RequestBody UserDto user) {
        // 判断账号是否重复
        SysUser theUser = sysUserService.getByAccount(user.getAccount());
        if (theUser != null) {
            throw new ServiceException("账号已存在");
        }

        // 完善账号信息
        user.setSalt(RandomUtil.randomString(5));
        user.setPassword(MD5Util.encrypt(user.getPassword(), user.getSalt()));
        user.setStatus(ManagerStatus.OK.getCode());
        user.setCreatetime(new Date());
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(user, sysUser);
        this.sysUserService.save(sysUser);
        return Result.createSuccess();
    }

    /**
     * 修改自己的信息
     */
    @RequestMapping(value = "/edit_self", method = RequestMethod.POST)
    @Permission
    @Menu(name = "修改自己的信息", code = "mgr_edit_self", parentCode = "mgr")
    public Object editSelf(@RequestBody UserDto user) {
        user.setId(getUserId());
        SysUser oldUser = sysUserService.getById(user.getId());
        sysUserService.updateById(editUser(user, oldUser));
        return Result.createSuccess();
    }

    /**
     * 修改用户信息
     */
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @Permission
    @Menu(name = "修改用户信息", code = "mgr_edit", parentCode = "mgr")
    public Object edit(@RequestBody UserDto user) {
        SysUser oldUser = sysUserService.getById(user.getId());
        sysUserService.updateById(editUser(user, oldUser));
        return Result.createSuccess();
    }

    private static SysUser editUser(UserDto newUser, SysUser oldUser) {
        if (newUser == null || oldUser == null) {
            return oldUser;
        } else {
            if (StrUtil.isNotEmpty(newUser.getName())) {
                oldUser.setName(newUser.getName());
            }
            if (ObjectUtil.isNotEmpty(newUser.getBirthday())) {
                oldUser.setBirthday(newUser.getBirthday());
            }
            if (ObjectUtil.isNotEmpty(newUser.getSex())) {
                oldUser.setSex(newUser.getSex());
            }
            if (StrUtil.isNotEmpty(newUser.getEmail())) {
                oldUser.setEmail(newUser.getEmail());
            }
            if (StrUtil.isNotEmpty(newUser.getPhone())) {
                oldUser.setPhone(newUser.getPhone());
            }
            return oldUser;
        }
    }

    /**
     * 删除用户（逻辑删除）
     */
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    @Permission
    @Menu(name = "删除用户（逻辑删除）", code = "mgr_delete", parentCode = "mgr")
    public Object delete(String userId) {
        if (StrUtil.isEmpty(userId)) {
            throw new ServiceException("请求为空");
        }
        //不能删除admin用户
        if (userId.equals(Const.ADMIN_ID)) {
            throw new ServiceException("无权操作");
        }
        this.sysUserService.setStatus(userId, ManagerStatus.DELETED.getCode());
        return Result.createSuccess();
    }

    /**
     * 重置用户的密码
     */
    @RequestMapping(value = "/reset", method = RequestMethod.GET)
    @Permission
    @Menu(name = "重置用户的密码", code = "mgr_reset", parentCode = "mgr")
    public Object reset(String userId) {
        if (StrUtil.isEmpty(userId)) {
            throw new ServiceException("请求为空");
        }
        SysUser user = this.sysUserService.getById(userId);
        user.setSalt(RandomUtil.randomString(5));
        user.setPassword(MD5Util.encrypt(Const.DEFAULT_PWD, user.getSalt()));
        this.sysUserService.updateById(user);
        return Result.createSuccess();
    }

    /**
     * 冻结用户
     */
    @RequestMapping(value = "/freeze", method = RequestMethod.GET)
    @Permission
    @Menu(name = "冻结用户", code = "mgr_freeze", parentCode = "mgr")
    public Object freeze(String userId) {
        if (StrUtil.isEmpty(userId)) {
            throw new ServiceException("请求为空");
        }
        //不能冻结admin
        if (userId.equals(Const.ADMIN_ID)) {
            throw new ServiceException("无权操作");
        }
        this.sysUserService.setStatus(userId, ManagerStatus.FREEZED.getCode());
        return Result.createSuccess();
    }

    /**
     * 解除冻结用户
     */
    @RequestMapping(value = "/unfreeze", method = RequestMethod.GET)
    @Permission
    @Menu(name = "解除冻结用户", code = "mgr_unfreeze", parentCode = "mgr")
    public Object unfreeze(String userId) {
        if (StrUtil.isEmpty(userId)) {
            throw new ServiceException("请求为空");
        }
        this.sysUserService.setStatus(userId, ManagerStatus.OK.getCode());
        return Result.createSuccess();
    }

    /**
     * 分配用户角色
     */
    @RequestMapping(value = "/setRole", method = RequestMethod.POST)
    @Permission
    @Menu(name = "分配用户角色", code = "mgr_setRole", parentCode = "mgr")
    public Object setRole(@RequestBody UserRoles userRoles) {
        if (ObjectUtil.isAllEmpty(userRoles.getUserId(), userRoles.getRoleIds())) {
            throw new ServiceException("请求为空");
        }
        //不能修改超级管理员
        if (userRoles.getUserId().equals(Const.ADMIN_ID)) {
            throw new ServiceException("无权操作");
        }
        this.sysUserService.setRoles(userRoles.getUserId(), userRoles.getRoleIds());
        return Result.createSuccess();
    }
}
